package com.pro.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.pro.domain.*;
import com.pro.mapper.*;
import com.pro.service.UserService;
import com.pro.service.exception.ServiceException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestHeader;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
@Transactional
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RecordMapper recordMapper;

    @Autowired
    private FilmMapper filmMapper;

    @Autowired
    private TheaterRoomMapper theaterRoomMapper;

    @Autowired
    private CinemaMapper cinemaMapper;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Override
    public Map<String, Object> userLogin(String username, String password) {
        Map<String, Object> map = new HashMap<String, Object>();
        UUID token = UUID.randomUUID();

        //1.查看redis里面是否有该用户
        List<Object> user1 = redisTemplate.boundHashOps("user").values();
        if (user1 != null) {
            for (Object o : user1) {
                User user = JSONObject.parseObject((String) o, User.class);
                if (username.equals(user.getUsername())) {
                    if (password.equals(user.getPassword())) {
                        String s = JSON.toJSONString(user);
                        //保存登录信息
                        redisTemplate.boundValueOps(String.valueOf(token)).set(s, 1, TimeUnit.DAYS);
                        map.put("token", token);
                        map.put("user", user);
                        return map;
                    } else {
                        throw new ServiceException("err02", "用户用户名或者密码错误");
                    }
                }
            }
        } //如果redis里面没有
        //1.检查用户是否存在
        QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
        queryWrapper.eq("username", username);
        List<User> userList = userMapper.selectList(queryWrapper);
        if (userList.size() <= 0) {
            throw new ServiceException("err01", "用户不存在");
        }
        //2.检查密码
        for (User user : userList) {
            if (!password.equals(user.getPassword())) {
                throw new ServiceException("err02", "用户用户名或者密码错误");
            }
        }

        //3.把新查到的用户加到redis里面
        String jsonString = JSON.toJSONString(userList.get(0));
        //保存信息
        redisTemplate.boundHashOps("user").put("user:id:" + userList.get(0).getUserId(), jsonString);
        //保存登录信息
//            redisTemplate.boundHashOps("user").put(token, jsonString);
        redisTemplate.boundValueOps(String.valueOf(token)).set(jsonString, 1, TimeUnit.DAYS);
        map.put("token", token);
        map.put("user", userList.get(0));
        return map;

    }

    @Override
    public User queryUserByRedis(String token) {
        //1.在redis里面的登录记录里查用户信息(json串)
        String s = getRedisUserLogin(token);
        return JSONObject.parseObject(s, User.class);
    }

    @Override
    public List<Record> queryUserSelfRecord(String token) {
        //1.在redis里面的登录记录里查用户信息(json串)
        String s = getRedisUserLogin(token);
        User user = JSONObject.parseObject(s, User.class);

        List<Object> record1 = redisTemplate.boundHashOps("record").values();
        List<Record> recordList = new ArrayList<Record>();
        if (record1 != null) {
            for (Object o : record1) {
                Record record = JSONObject.parseObject((String) o, Record.class);
                if (user.getUserId().equals(record.getUserId())) {
                    recordList.add(record);
                }
            }
            if (recordList.size() <= 0) {
                throw new ServiceException("err07", "您暂时还未订购任何电影票，赶快去订购吧");
            }
        }
        return recordList;
    }

    @Override
    public void BuyTickets(String token, Record record1, String[] num) {
        if (num.length == 0) {
            throw new ServiceException("err09", "您还未选座位哦哦");
        }
        //这里判断作为有没有被占了(前端有 两人买一票 的bug)
        for (int i = 0; i < num.length; i++) {
            QueryWrapper<Record> recordQueryWrapper = new QueryWrapper<Record>();
            recordQueryWrapper.eq("position", num);
            recordQueryWrapper.eq("film_id", record1.getFilmId());
            recordQueryWrapper.eq("tr_id", record1.getTrId());
            recordQueryWrapper.eq("cinema_id", record1.getCinemaId());
            recordQueryWrapper.eq("start_time", record1.getStartTime());
            recordQueryWrapper.eq("end_time", record1.getEndTime());
            List<Record> recordList = recordMapper.selectList(recordQueryWrapper);
            if (recordList.size() > 0) {
                throw new ServiceException("err10", "有座位已经被别人买了，请刷新页面重新购买");
            }
        }

        //添加到数据库
        String s = getRedisUserLogin(token);
        User user = JSONObject.parseObject(s, User.class);
        //修改用户的money
        double newMoney = user.getMoney() - record1.getPrice() * num.length;
        if (newMoney < 0) {
            throw new ServiceException("err08", "余额不足");
        }
        user.setMoney(newMoney);
        userMapper.updateById(user);
        //更新redis里面的用户信息改变
        redisTemplate.opsForValue().set(token, JSON.toJSONString(user), 12, TimeUnit.HOURS);
        redisTemplate.opsForHash().put("user", "user:id:" + user.getUserId(), JSON.toJSONString(user));

        record1.setUserId(user.getUserId());
        record1.setBuyTime(getTime());
        for (String value : num) {
            record1.setPosition(value);
            recordMapper.insert(record1);
        }

        //把购买记录添加到redis
        QueryWrapper<Record> queryWrapper = new QueryWrapper<Record>();
        queryWrapper.eq("user_id", user.getUserId());
        List<Record> records = recordMapper.selectList(queryWrapper);
        for (Record record : records) {
            QueryWrapper<User> userQueryWrapper = new QueryWrapper<User>();
            userQueryWrapper.eq("user_id", record.getUserId());
            record.setUser(userMapper.selectOne(userQueryWrapper));

            QueryWrapper<Film> filmQueryWrapper = new QueryWrapper<Film>();
            filmQueryWrapper.eq("film_id", record.getFilmId());
            record.setFilm(filmMapper.selectOne(filmQueryWrapper));

            QueryWrapper<TheaterRoom> roomQueryWrapper = new QueryWrapper<TheaterRoom>();
            roomQueryWrapper.eq("tr_id", record.getTrId());
            record.setTheaterRoom(theaterRoomMapper.selectOne(roomQueryWrapper));

            QueryWrapper<Cinema> cinemaQueryWrapper = new QueryWrapper<Cinema>();
            cinemaQueryWrapper.eq("cinema_id", record.getCinemaId());
            record.setCinema(cinemaMapper.selectOne(cinemaQueryWrapper));

            //永久存到redis
            redisTemplate.opsForHash().put("record", "record:id:" + record.getId(), JSON.toJSONString(record));
        }

    }

    /**
     * 得到买票的时间
     *
     * @return
     */
    private String getTime() {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return format.format(Calendar.getInstance().getTime());
    }

    /**
     * 得到redis里面的用户信息
     * @param token
     * @return
     */
    private String getRedisUserLogin(String token) {
        String s = redisTemplate.opsForValue().get(token);
        if (s == null || "".equals(s)) {
            throw new ServiceException("err05", "登录过期，请重新登入");
        }
        return s;
    }
}
